package com.geeguo.ebuilder.client.base.core.utils;

import com.geeguo.ebuilder.client.base.core.config.SystemConfig;
import com.geeguo.ebuilder.core.common.exception.ApplicationException;
import com.geeguo.ebuilder.core.common.model.vo.FileVO;
import com.geeguo.ebuilder.core.common.utils.key.UUIDGenerator;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;

@Component
public class FileHelper {

    private static SystemConfig systemConfig;

    @Autowired
    public void setSystemConfig(SystemConfig systemConfig) {
        FileHelper.systemConfig = systemConfig;
    }

    public static String getFullFilePath(String filePath) {
        String fileBasePath = systemConfig.getFileBasePath();
        if (StringUtils.isEmpty(fileBasePath)) {
            throw new ApplicationException("未配置系统文件存储目录");
        } else if (!fileBasePath.endsWith("/")) {
            fileBasePath = fileBasePath + "/";
        }
        return fileBasePath + filePath;
    }

    public static String getFileUrl(String filePath) {
        String fileBaseUrl = systemConfig.getFileBaseUrl();
        if (StringUtils.isEmpty(fileBaseUrl)) {
            throw new ApplicationException("未配置系统文件读取地址");
        } else if (!fileBaseUrl.endsWith("/")) {
            fileBaseUrl = fileBaseUrl + "/";
        }
        return fileBaseUrl + filePath;
    }

    public static FileVO upload(String tenantFolder, String parentFolder, MultipartFile file) throws ApplicationException, IOException {
        return upload(tenantFolder, parentFolder,  null, file);
    }

    public static FileVO upload(String tenantFolder, String parentFolder, String leafFolder, MultipartFile multipartFile) throws ApplicationException, IOException {
        // 系统文件存储目录，所有上传的文件都统一存储在指定的系统文件存储目录下
        String fileBasePath = systemConfig.getFileBasePath();
        if (StringUtils.isEmpty(fileBasePath)) {
            throw new ApplicationException("文件上传失败，未配置系统文件存储目录");
        } else if (!fileBasePath.endsWith("/")) {
            fileBasePath = fileBasePath + "/";
        }
        // 租户目录，不同业务的文件，存储在不同的租户目录下，
        if (StringUtils.isEmpty(tenantFolder)) {
            throw new ApplicationException("文件上传失败，未指定文件存储租户路径");
        } else if (!tenantFolder.endsWith("/")) {
            tenantFolder = tenantFolder + "/";
        }
        // 根目录，不同业务的文件，存储在不同的根目录下，
        if (StringUtils.isEmpty(parentFolder)) {
            throw new ApplicationException("文件上传失败，未指定文件存储根路径");
        } else if (!parentFolder.endsWith("/")) {
            parentFolder = parentFolder + "/";
        }
        // 子目录，如果为空，则生成默认子目录
        if (StringUtils.isEmpty(leafFolder)) {
            leafFolder = getDefaultLeafFolder();
        }
        if (!leafFolder.endsWith("/")) {
            leafFolder = leafFolder + "/";
        }
        // 获取原始文件名，如果原始文件名为空，不能保存
        String originalFilename = multipartFile.getOriginalFilename();
        if (StringUtils.isEmpty(originalFilename)) {
            throw new ApplicationException("文件上传失败，文件没有文件名");
        }
        // 获取文件扩展名，如果文件扩展名为空，不能保存
        String extension = "";
        int dotIndex = originalFilename.lastIndexOf('.');
        if (dotIndex > 0) {
            extension = originalFilename.substring(dotIndex).toLowerCase();
        }
        if (StringUtils.isEmpty(extension)) {
            throw new ApplicationException("文件上传失败，文件没有文件名");
        }
        // 生成文件存储绝对路径
        StringBuilder filePath = new StringBuilder();
        filePath.append(tenantFolder);
        filePath.append(parentFolder);
        filePath.append(leafFolder);
        filePath.append(UUIDGenerator.getId());
        filePath.append(extension);
        // 写入文件
        File file = new File(fileBasePath + filePath.toString());
        FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());
        // 返回文件信息
        FileVO fileVO = new FileVO();
        fileVO.setFileName(originalFilename);
        fileVO.setExtension(extension);
        fileVO.setFilePath(filePath.toString());
        fileVO.setFileUrl(getFileUrl(filePath.toString()));
        return fileVO;
    }

    public static boolean remove(String filePath) {
        String fullFilePath = getFullFilePath(filePath);
        File file = new File(fullFilePath);
        if (file.exists()) {
            return file.delete();
        }
        return true;
    }

    private static String getDefaultLeafFolder() {
        Calendar calendar = Calendar.getInstance();
        StringBuilder leafFolder = new StringBuilder();
        leafFolder.append(calendar.get(Calendar.YEAR));
        leafFolder.append("/");
        leafFolder.append(String.format("%02d", calendar.get(Calendar.MONTH) + 1));
        leafFolder.append("/");
        leafFolder.append(String.format("%02d", calendar.get(Calendar.DATE)));
        return leafFolder.toString();
    }
}
